﻿// @include "Browser.js"
// @include "Type.js"
// @include "Argument.js"
/**
 * @fileOverview Function扩展工具
 * 
 * @version qinglan_function 1.0
 * @static
 * @author wxq wxqqh@qq.com
 */
/**
 * 命名空间
 * 
 * @namespace
 * @type Object
 */
window.qinglan = window.qinglan || {};
/**
 * Function扩展命名空间
 * 
 * @type Object
 */
qinglan.Function = qinglan.Function || {};
/**
 * 进行方法绑定
 * 
 * @param {Object}
 *            obj 绑定的对象
 * @param {Function}
 *            fun 绑定的方法
 * @return {Object} 可执行对象
 */
qinglan.Function.bind = function(obj, fun) {
	return function() {
		qinglan.Type.isString(fun) && (fun = obj[fun]);
		!qinglan.Type.isFunction(fun) && (fun = qinglan.Function.emptyFun);
		return fun.apply(obj, qinglan.Argument.toArray(arguments, 2));
	};
};
/**
 * 空的方法
 * 
 * @static
 * @type Function
 */
qinglan.Function.emptyFun = function() {
};

/**
 * 方法反射<br/>
 * 根据tag得到方法的相应部分内容
 * <ul>
 * 		<li><b>body</b> : 方法体</li>
 * 		<li><b>param</b> : 方法参数</li>
 * 		<li><b>name</b> : 方法名字 但是对匿名方法无效</li>
 * 		<li><b>scope</b> : 方法调用链</li>
 *		<li><b>anonymous</b> : 匿名方法方法字串</li>
 * </ul>
 * 
 * @param {Function} fun 方法
 * @param {String} tag 获取反射类型
 * @type Function
 * @public
 * @see http://www.cnblogs.com/rubylouvre/archive/2011/05/30/2062953.html author司徒正美
 */
qinglan.Function.reflect=function(fun,tag){
	if(qinglan.Type.isFunction(fun)){
		var _r_function = /^function\b\s*([\$\S]*)\s*\(/;//得到方法名
		var _r_codebody = /[^{]*\{([\d\D]*)\}$/;//得到方法体
		var _r_params = /[^\(]*\(([^\)]*)\)[\d\D]*/;//得到方法参数
		tag = (tag || 'body').toLowerCase();
		with (func.toString()) {
			return (tag == 'body') ? replace(_r_codebody, '$1').replace(/^\s*|\s*$/g, '')
			: (tag == 'param') ? ((tag=replace(_r_params, '$1')) ? tag.split(/[,\s]+/) : [])
			: (tag == 'name') ? match(_r_function)[1]
			: (tag == 'scope') ? '[function (' +arguments.callee(func, 'param')+ ') {\n' +arguments.callee(func, 'body')+ '\n}][0]'
			: (tag == 'anonymous') ? Function.apply(this, arguments.callee(func, 'param').concat(arguments.callee(func, 'body')))
			: 'Block() with bad arguments.';
		};
	}
};
/**
 * 得到非匿名方法的名字
 * 
 * @public
 * @param {Function} fun 方法
 * @return {String} 方法名字
 */
qinglan.Function.getName=function(fun){
	if(qinglan.Type.isFunction(fun)){
		return fun.name || String(f).match(/^function\s*([^)]*)\(/)[1];
	}
};
